import datetime

from django.db import transaction
from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView, Response
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from libs.iPay import alipay
from utils.logging import logger
from utils.response import APIResponse
from . import models, serializers


# 商品群查
class ProductListAPIView(ListAPIView):
    queryset = models.Product.objects.filter(is_show=True).order_by('-order').all()
    serializer_class = serializers.ProductModelSerializer


# 支付接口
class PayAPIView(APIView):
    authentication_classes = [JSONWebTokenAuthentication]
    permission_classes = [IsAuthenticated]

    def post(self, request, *args, **kwargs):
        ser_obj = serializers.PayModelSerializer(data=request.data, context={"request": request})
        ser_obj.is_valid(raise_exception=True)
        ser_obj.save()
        logger.warning(f'用户{request.user}创建订单，订单号：f{ser_obj.order_no}')
        return APIResponse(results=ser_obj.pay_url)


# 支付成功后回调的接口
class PaySuccessAPIView(APIView):
    # 重点：要不要做登录认证，不需要：订单号可以获取你所需要的所有信息、回调参数有自己的安全校验、支付宝永远不可能通过token

    # 支付成功回调前台后转给后台
    def patch(self, request, *args, **kwargs):
        # print(request.query_params)
        data = request.query_params.dict()

        # 取出订单号
        out_trade_no = data.get("out_trade_no")

        # 必须取出sign和sign_type 做 异步返回结果的验签
        sign = data.pop("sign")
        sign_type = data.pop("sign_type")
        # 异步返回结果的验签
        is_success = alipay.verify(data, sign)
        if is_success:
            pass

            '''
            # 开启事务
            with transaction.atomic():
                # 一般不在同步回调直接操作订单状态
                order_queryset = models.Order.objects.filter(out_trade_no=out_trade_no)
                order_queryset.update(trade_no = data.get("trade_no"),order_status = 1)

                # 修改会员过期时间和会员类别
                order_obj = order_queryset.first()
                now = datetime.datetime.now()
                validity_date = order_obj.product.validity_date
                exp_date = now + datetime.timedelta(validity_date)
                order_obj.user.exp_date = exp_date
                order_obj.user.vip_type = order_obj.vip_type
                order_obj.user.save()
            '''
        return Response('同步回调完成')

    # 异步支付宝回调接口：公网下才能验证
    def post(self, request, *args, **kwargs):
        # 应该用data，不再是query_params
        data = request.data.dict()  # 回调参数，是QueryDict类型，不能直接调用pop方法

        # 取出订单号
        out_trade_no = data.get("out_trade_no")

        # 必须取出sign和sign_type 做 异步返回结果的验签
        sign = data.pop("sign")
        sign_type = data.pop("sign_type")
        # 异步返回结果的验签
        is_success = alipay.verify(data, sign)
        # 异步回调有这些信息
        if is_success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
            try:
                order_obj = models.Order.objects.get(out_trade_no=out_trade_no)
                if order_obj.order_status != 1:
                    # 开启事务
                    with transaction.atomic():
                        order_obj.trade_no = data.get("trade_no")
                        order_obj.order_status = 1
                        order_obj.save()

                        # 修改会员过期时间和会员类别
                        now = datetime.datetime.now()
                        validity_date = order_obj.product.validity_date
                        exp_date = now + datetime.timedelta(validity_date)
                        order_obj.user.exp_date = exp_date
                        order_obj.user.vip_type = order_obj.vip_type
                        order_obj.user.save()
                        logger.warning('%s订单完成支付' % out_trade_no)
                return Response('success')
            except:
                pass
        return Response('failed')
